﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Runtime.Serialization;
using System.Xml;
using System.IO;
using System.ComponentModel;
using System.Security.Cryptography;

namespace ASoft
{
    public class AppUtility
    {
        static AppUtility() { }

        //public static string RootPath
        //{
        //    get
        //    {
        //        var result = ConfigurationManager.AppSettings["RootPath"];
        //        if (string.IsNullOrWhiteSpace(result))
        //        {
        //            return AppDomain.CurrentDomain.BaseDirectory;
        //        }
        //        return result;
        //    }
        //}


        public static void SerializerWrite<T>(T obj, string fileName, IEnumerable<Type> knownTypes)
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(T), knownTypes);
            XmlWriterSettings settings = new XmlWriterSettings { Indent = true, Encoding = Encoding.UTF8 };
            var dirName = Path.GetDirectoryName(fileName);
            if (!Directory.Exists(dirName))
            {
                Directory.CreateDirectory(dirName);
            }
            using (XmlWriter writer = XmlWriter.Create(fileName, settings))
            {
                serializer.WriteObject(writer, obj);
            }
        }

        public static T SerializerRead<T>(string fileName, IEnumerable<Type> knownTypes)
        {
            T result;
            using (var xmlReader = new XmlTextReader(System.IO.File.Open(fileName, System.IO.FileMode.Open)))
            {
                DataContractSerializer serializer = new DataContractSerializer(typeof(T), knownTypes);
                result = (T)serializer.ReadObject(xmlReader);
            }

            return result;
        }

        public static string GetFileName(string fileNameNoEx)
        {
            return fileNameNoEx + ".asoft";
        }
        /// <summary>
        /// 转换为时分秒字符串
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string ConvertShortToTimeString(short value)
        {
            var h = Math.Floor((double)value / 3600);
            var m = Math.Floor((double)(value - h * 3600) / 60);
            var s = value - h * 3600 - m * 60;
            return string.Format("{0}:{1}:{2}", h.ToString("00"), m.ToString("00"), s.ToString("00"));
        }

        /// <summary>
        /// 从时分秒字符串转换为数字
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public static short ConvertTimeStringToShort(string time)
        {
            var timeString = DateTime.Parse(time).ToString("HH:mm:ss");
            var ary = timeString.Split(':');
            var result = short.Parse(ary[0]) * 3600 + short.Parse(ary[1]) * 60 + short.Parse(ary[2]);
            return (short)result;
        }
        /// <summary>
        /// 转换为时分字符串
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string ConvertShortToTimeString1(short value)
        {
            var h = Math.Floor((double)value / 60);
            var m = value - h * 60;
            return string.Format("{0}:{1}", h.ToString("00"), m.ToString("00"));
        }

        /// <summary>
        /// 从时分字符串转换为数字
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public static short ConvertTimeStringToShort1(string time)
        {
            var ary = time.Split(':');
            var result = short.Parse(ary[0]) * 60 + short.Parse(ary[1]);
            return (short)result;
        }




        public static string GetEnumDescription(object value)
        {
            var type = value.GetType();
            var memInfo = type.GetMember(value.ToString());
            var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
            var description = ((DescriptionAttribute)attributes[0]).Description;
            return description;
        }

        public static Dictionary<T, string> GetEnumSources<T>()
        {
            var result = new Dictionary<T, string>();
            typeof(T).GetEnumValues().Cast<Object>()
                .ToList()
                .ForEach(p => result[(T)p] = GetEnumDescription(p));
            return result;
        }

        public static string GetMsgRecordData(Msg.MsgBase msg)
        {
            var data = msg.GetData();
            return GetByteString(data);
        }

        public static string GetByteString(byte[] bytes)
        {
            return string.Join(" ", bytes.Select(p => p.ToString("X2")));
        }

        public static decimal TemperatureToDisplay(short realValue)
        {
            return (decimal)((decimal)realValue / 10 - 50);
        }

        public static short TemperatureToReal(decimal displayValue)
        {
            return (short)((displayValue + 50) * 10);
        }

        public static decimal WindSpeedToDisplay(short realValue)
        {
            return (decimal)((decimal)realValue / 10);
        }

        public static short WindSpeedToReal(decimal displayValue)
        {
            return (short)(displayValue * 10);
        }

        public static byte SoilMoistureToDisplay(byte realValue)
        {
            return HexTo10(realValue);
        }

        public static byte HexTo10(byte hex)
        {
            return (byte)((hex >> 4) * 10 + (hex - ((hex >> 4) << 4)));
        }

        public static byte SoilMoistureToReal(byte displayValue)
        {
            return (byte)((((int)((decimal)displayValue / 10)) << 4) + (displayValue - ((int)((decimal)displayValue / 10)) * 10));
        }

        public static byte GetACC0(byte value)
        {
            return (byte)(value - ((value >> 1) << 1));
        }


        #region 集合

        static Dictionary<byte, string> _风向集合 = new Dictionary<byte, string>();
        public static Dictionary<byte, string> 风向集合
        {
            get
            {
                if (_风向集合.Count == 0)
                {
                    _风向集合.Add(0, "无");
                    _风向集合.Add(1, "东方");
                    _风向集合.Add(2, "东北");
                    _风向集合.Add(3, "北方");
                    _风向集合.Add(4, "西北");
                    _风向集合.Add(5, "西方");
                    _风向集合.Add(6, "西南");
                    _风向集合.Add(7, "南方");
                    _风向集合.Add(8, "东南");
                }
                return _风向集合;
            }
        }

        public static string Get风向字符串(byte index)
        {
            string result = "";
            风向集合.TryGetValue(index, out result);
            return result;
        }

        public static string Get雨雪字符串(byte index)
        {
            string result = "";
            雨雪集合.TryGetValue(index, out result);
            return result;
        }

        static Dictionary<byte, string> _雨雪集合 = new Dictionary<byte, string>();
        public static Dictionary<byte, string> 雨雪集合
        {
            get
            {
                if (_雨雪集合.Count == 0)
                {
                    _雨雪集合.Add(0, "无");
                    _雨雪集合.Add(1, "有");

                }
                return _雨雪集合;
            }
        }

        static Dictionary<byte, string> _计时方式集合 = new Dictionary<byte, string>();
        public static Dictionary<byte, string> 计时方式集合
        {
            get
            {
                if (_计时方式集合.Count == 0)
                {
                    _计时方式集合.Add(0, "分");
                    _计时方式集合.Add(1, "秒");
                }
                return _计时方式集合;
            }
        }

        static Dictionary<byte, string> _手动自动标志集合 = new Dictionary<byte, string>();
        public static Dictionary<byte, string> 手动自动标志集合
        {
            get
            {
                if (_手动自动标志集合.Count == 0)
                {
                    _手动自动标志集合.Add(0, "手动");
                    _手动自动标志集合.Add(1, "自动");
                }
                return _手动自动标志集合;
            }
        }

        static Dictionary<byte, string> _手动运行方向集合 = new Dictionary<byte, string>();
        public static Dictionary<byte, string> 手动运行方向集合
        {
            get
            {
                if (_手动运行方向集合.Count == 0)
                {
                    _手动运行方向集合.Add(0, "合拢");
                    _手动运行方向集合.Add(1, "展开");
                }
                return _手动运行方向集合;
            }
        }

        static Dictionary<byte, string> _湿帘泵手动运行方向集合 = new Dictionary<byte, string>();
        public static Dictionary<byte, string> 湿帘泵手动运行方向集合
        {
            get
            {
                if (_湿帘泵手动运行方向集合.Count == 0)
                {
                    _湿帘泵手动运行方向集合.Add(0, "停");
                    _湿帘泵手动运行方向集合.Add(1, "开");

                }
                return _湿帘泵手动运行方向集合;
            }
        }



        static Dictionary<byte, string> _有效性集合 = new Dictionary<byte, string>();
        public static Dictionary<byte, string> 有效性集合
        {
            get
            {
                if (_有效性集合.Count == 0)
                {
                    _有效性集合.Add(0, "无效");
                    _有效性集合.Add(1, "有效");
                }
                return _有效性集合;
            }
        }

        static Dictionary<byte, string> _灌溉手动操作集合 = new Dictionary<byte, string>();
        public static Dictionary<byte, string> 灌溉手动操作集合
        {
            get
            {
                if (_灌溉手动操作集合.Count == 0)
                {
                    _灌溉手动操作集合.Add(0, "关");
                    _灌溉手动操作集合.Add(1, "开");
                }
                return _灌溉手动操作集合;
            }
        }

        static Dictionary<bool, string> _启用集合 = new Dictionary<bool, string>();
        public static Dictionary<bool, string> 启用集合
        {
            get
            {
                if (_启用集合.Count == 0)
                {
                    _启用集合.Add(false, "无效");
                    _启用集合.Add(true, "有效");
                }
                return _启用集合;
            }
        }

        #endregion

        public static string GetHash(string target)
        {
            using (MD5 md5 = MD5.Create())
            {
                byte[] data = Encoding.Unicode.GetBytes(target);
                byte[] hash = md5.ComputeHash(data);

                return Convert.ToBase64String(hash);
            }
        }

        public static void CopyPropertyData(Type propertyAttributeType, object sourceObject, object targetObject)
        {
            var type = sourceObject.GetType();
            type.GetProperties().Where(p => p.GetCustomAttributes(propertyAttributeType, true).Length > 0)
                .ToList()
                .ForEach(p =>
                    p.SetValue(targetObject, p.GetValue(sourceObject, null), null));

        }
    }
}
